//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2011, Steven Oda
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the copyright holder nor the names of any
//       contributors may be used to endorse or promote products derived from
//       this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//////////////////////////////////////////////////////////////////////////////

#include <string>
#include <fstream>
#include <sstream>
#include "Level.h"
using namespace std;


Level::Level(){
    //show the grid
    theWorld.Add(new GridActor(), -1);
    tempTile.setPosition(0.0,0.0);
    tempTile.setColor(0,0,0);
}

void Level::load( string levelName ){

    //open level ini file
    ifstream file;
    levelName = "Config/Level/" + levelName + ".ini";
    file.open(levelName.c_str());

    //read in the file to a list of actors
    Vector2 position;
    string line;
    string s_x, s_y;//holds string x and string y positions
    int a,b,c;
    Tile tempTile;

    list<TileType>::iterator it;

    while(! file.eof()){
        getline(file,line);
        if(line.substr(0,10) == "position=["){
            a = line.find_first_of("[");
            b = line.find_first_of(",");
            c = line.find_first_of("]");
            s_x = line.substr(a+1, b-a-1);
            s_y = line.substr(b+1, c-b-1);
            position.X = atof(s_x.c_str());
            position.Y = atof(s_y.c_str());
            editTile(position);
        }
        else if(line.substr(0,5) == "type="){
            s_x = line.substr(5, line.size() - 5);
            ConsoleLog *C = new ConsoleLog();
            C->Log(s_x);
            for ( it=tileTypeList.begin() ; it != tileTypeList.end(); it++ ){
                if(it->name == s_x){
                    C->Log("type found.");
                    stringstream ss;
                    ss<< it->blue;
                    C->Log( ss.str() );
                    tempTileType = *it;
                }
            }
        }
    }
    //close the level ini file
    file.close();
}

void Level::save( string levelName ){
    //open the level ini file
    ofstream file;
    levelName = "Config/Level/" + levelName + ".ini";
    file.open(levelName.c_str());

    //overwrite the file with the new data
    list<Tile>::iterator it;
    float x,y;
    string type;
    int counter = 0;
    while( !tileList.empty() ){
        counter++;
        x = tileList.front().x;
        y = tileList.front().y;
        type = tileList.front().getType().name;
        ConsoleLog *c = new ConsoleLog();
        stringstream ss;
        ss<<x<<", "<<y;
        c->Log( ss.str());
        tileList.pop_front();

        file<<"[Tile_"<<counter<<"]\n";
        file<<"type="<<type<<"\n";
        file<<"position=["<<x<<","<<y<<"]\n\n";
    }

    //close the file
    file.close();
}

void Level::editTile(Vector2 position){
    //change the selected tile
    tempTile.setPosition(position.X, position.Y);
    bool found = false;
    //remove any tile at that position
    list<Tile>::iterator it;
    if(!tileList.empty()){
        for ( it=tileList.begin() ; it != tileList.end(); it++ ){
            if(it->checkPosition(tempTile.x, tempTile.y)){
                it->remove();
                tileList.erase(it++);
                found = true;
            }
        }
    }

    if(!found){
    //add the tile to the position
    Tile myTempTile;
    myTempTile.setPosition(position.X, position.Y);
    myTempTile.setType(tempTileType);//.getType());
    tileList.push_back(myTempTile);
    tileList.back().add();
    }
}

void Level::loadArchetype( std::string actorDef){
    //open the Archetype ini file
    ifstream file;
    actorDef= "Config/ActorDef/" + actorDef + ".ini";
    file.open(actorDef.c_str());

    ConsoleLog *C = new ConsoleLog();

    string line;
    int a,b,c;
    string s_x, s_y, s_z;
    bool nextInput = false;

    while(!file.eof()){
        getline(file, line);

        //load a name to temp tile type
        if( line.substr(0,1) == "[")
        {
            if(nextInput)//if this is the
                tileTypeList.push_back(tempTileType);
            else
                nextInput = true;
            a = line.find_first_of("]");
            s_x = line.substr(1,a-1);
            C->Log(s_x);
            tempTileType.name = s_x;
        }
        //load a color to temp tile type
        else if(line.substr(0,7) == "color=["){
            a = line.find_first_of(",");
            b = line.find_last_of (",");
            c = line.find_first_of("]");
            s_x = line.substr(7,a-7);
            s_y = line.substr(a+1, b-a-1);
            s_z = line.substr(b+1, c-b-1);
            tempTileType.red =  atof(s_x.c_str());
            tempTileType.green= atof(s_y.c_str());
            tempTileType.blue = atof(s_z.c_str());
            tempTile.setColor(tempTileType.red, tempTileType.blue, tempTileType.green);
        }
    }
    //load the last
    tileTypeList.push_back(tempTileType);
    file.close();
}

void Level::setTempTileType(int type){
    list<TileType>::iterator it;
    it=tileTypeList.begin();

    if(tileTypeList.size()>=type){
        for(int i = 0;i<type-1;i++)
            it++;
        tempTileType = *it;
    }
}
